package org.apache.click.doubleclick.inject;

/**
 * Underlying implementation should be responsible for injecting dependencies on all fields which is annotated
 * with {@link org.apache.click.doubleclick.inject.annotation.InjectBean}.
 *
 * @author Jahid Shohel(development.jsh@gmail.com)
 */
public interface DependencyInjector {
    /**
     * Injects all dependencies for member and inherited variables annotated with
     * {@link org.apache.click.doubleclick.inject.annotation.InjectBean}. Whether
     * a real instance or a proxy will be injected will be determined from the annotation.
     *
     * @param target The target instance to inject dependencies.
     * @param <T>    Type of the target.
     * @return the target with all dependency injected.
     */
    public <T> T injectDependencies(T target);

    /**
     * Injects all dependencies for member and inherited variables annotated with
     * {@link org.apache.click.doubleclick.inject.annotation.InjectBean}. A proxy will
     * be injected if the <i>injectProxy</i> is true. Otherwise the real instance will
     * be injected.
     *
     * @param target      The target instance to inject dependencies.
     * @param injectProxy Proxy will be injected if true, otherwise real instance
     *                    will be injected.
     * @param <T>         The type of the target.
     * @return the target with all dependencies injected.
     */
    public <T> T injectDependencies(T target, boolean injectProxy);

    /**
     * Gets bean for supplied class type. Always returns the first bean if more then one
     * bean is found for supplied class type.
     *
     * @param beanClass The bean class.
     * @param <T>       The type of the bean class.
     * @return Found bean instance.
     */
    public <T> T getBean(Class<T> beanClass);

    /**
     * Gets bean as proxy for supplied class type. Always returns the first bean if more
     * then one bean is found for supplied class type.
     *
     * @param beanClass The bean class.
     * @param <T>       The type of the bean class.
     * @return Generated proxy for found bean instance.
     */
    public <T> T getBeanAsProxy(Class<T> beanClass);
}
